<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="小龙的个人博客">
    <meta name="description" content="大数据架构师指南">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>小龙的个人博客</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 5.0.0"><link rel="alternate" href="/atom.xml" title="小龙的个人博客" type="application/atom+xml">
<link rel="stylesheet" href="/css/prism-tomorrow.css" type="text/css"></head>


<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">小龙的个人博客</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">小龙的个人博客</div>
        <div class="logo-desc">
            
            大数据架构师指南
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://gitee.com/carlosgxl" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://gitee.com/carlosgxl" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/0.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title"></h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        margin: 35px 0 15px 0;
        padding-left: 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        height: calc(100vh - 250px);
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                          <div class="article-tag">
                            <span class="chip bg-color">无标签</span>
                          </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2020-08-10
                </div>
                

                

                

                

                
            </div>
        </div>
        <hr class="clearfix">
        <div class="card-content article-card-content">
            <div id="articleContent">
                <h1 id="Spring-Cloud-Alibaba——微服务开发"><a href="#Spring-Cloud-Alibaba——微服务开发" class="headerlink" title="Spring Cloud Alibaba——微服务开发"></a>Spring Cloud Alibaba——微服务开发</h1><h2 id="Spring-Cloud-Alibaba-是什么？"><a href="#Spring-Cloud-Alibaba-是什么？" class="headerlink" title="Spring Cloud Alibaba 是什么？"></a>Spring Cloud Alibaba 是什么？</h2><p>​     Spring Cloud Alibaba 是阿里巴巴提供的微服务开发一站式解决方案，是阿里巴巴开源中间件与 Spring Cloud 体系的融合。包含开发分布式应用微服务的必需组件，方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。</p>
<h3 id="主要功能"><a href="#主要功能" class="headerlink" title=" 主要功能"></a> 主要功能</h3><p>  <strong>服务限流降级</strong>：默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入，可以在运行时通过控制台实时修改限流降级规则，还支持查看限流降级 Metrics 监控。<br>  <strong>服务注册与发现</strong>：适配 Spring Cloud 服务注册与发现标准，默认集成了 Ribbon 的支持。<br>  <strong>分布式配置管理</strong>：支持分布式系统中的外部化配置，配置更改时自动刷新。<br>  <strong>消息驱动能力</strong>：基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。<br>  <strong>分布式事务</strong>：使用 @GlobalTransactional 注解， 高效并且对业务零侵入地解决分布式事务问题。。<br>  <strong>阿里云对象存储</strong>：阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。<br>  <strong>分布式任务调度</strong>：提供秒级、精准、高可靠、高可用的定时（基于 Cron 表达式）任务调度服务。同时提供分布式的任务执行模型，如网格任务。网格任务支持海量子任务均匀分配到所有 Worker（schedulerx-client）上执行。<br>  <strong>阿里云短信服务</strong>：覆盖全球的短信服务，友好、高效、智能的互联化通讯能力，帮助企业迅速搭建客户触达通道。</p>
<h3 id="组件"><a href="#组件" class="headerlink" title=" 组件"></a> 组件</h3><p>  <strong>Sentinel</strong>：把流量作为切入点，从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。<br>  <strong>Nacos</strong>：一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。<br>  <strong>RocketMQ</strong>：一款开源的分布式消息系统，基于高可用分布式集群技术，提供低延时的、高可靠的消息发布与订阅服务。<br>  <strong>Dubbo</strong>：ApacheDubbo™ 是一款高性能 Java RPC 框架。<br>  <strong>Seata</strong>：阿里巴巴开源产品，一个易于使用的高性能微服务分布式事务解决方案。<br>  <strong>Alibaba</strong> Cloud ACM：一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。<br>  <strong>Alibaba Cloud OSS</strong>: 阿里云对象存储服务（Object Storage Service，简称 OSS），是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。<br>  <strong>Alibaba Cloud SchedulerX</strong>: 阿里中间件团队开发的一款分布式任务调度产品，提供秒级、精准、高可靠、高可用的定时（基于 Cron 表达式）任务调度服务。<br>  <strong>Alibaba Cloud SMS</strong>: 覆盖全球的短信服务，友好、高效、智能的互联化通讯能力，帮助企业迅速搭建客户触达通道。</p>
<p>学习<a target="_blank" rel="noopener" href="http://blog.didispace.com/spring-cloud-alibaba-significance/"> 程序猿DD-翟永超-Spring Cloud Alibaba基础教程</a></p>
<h2 id="为什么不使用Spring-Cloud"><a href="#为什么不使用Spring-Cloud" class="headerlink" title="为什么不使用Spring Cloud"></a>为什么不使用Spring Cloud</h2><p>​    因为需要考虑Eureka 宣布闭源的问题。然而官方说的是 Eureka 2.0 的开源工作已经停止，依赖于开源库里面的 Eureka 2.x 分支构建的项目或者相关代码，风险自负！Spring Cloud 还是在 1.x 上面开发的，但有必要考虑到这一点所以可以使用Spring Cloud Alibaba<br><img src="https://img-blog.csdnimg.cn/20200408232129717.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<blockquote>
<p>The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.<br>Eureka 1.x is a core part of Netflix’s service discovery system and is still an active project.</p>
</blockquote>
<h2 id="使用-Nacos-Discovery-Starter-完成微服务应用的服务注册与发现"><a href="#使用-Nacos-Discovery-Starter-完成微服务应用的服务注册与发现" class="headerlink" title="使用 Nacos Discovery Starter 完成微服务应用的服务注册与发现"></a>使用 Nacos Discovery Starter 完成微服务应用的服务注册与发现</h2><h3 id="组件版本关系"><a href="#组件版本关系" class="headerlink" title=" 组件版本关系"></a> 组件版本关系</h3><p><img src="https://img-blog.csdnimg.cn/20200410110722384.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<h3 id="声明版本"><a href="#声明版本" class="headerlink" title=" 声明版本"></a> 声明版本</h3><p>  1、在 公共项目dependencyManagement 中添加如下配置</p>
<pre><code>&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-alibaba-dependencies&lt;/artifactId&gt;
            &lt;version&gt;2.2.0.RELEASE&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;
1234567891011</code></pre>
<h3 id="引入依赖"><a href="#引入依赖" class="headerlink" title=" 引入依赖"></a> 引入依赖</h3><p>  2、然后在 dependencies 中添加依赖，引入 Nacos Discovery Starter</p>
<pre><code>    &lt;!--        服务注册/发现--&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;/artifactId&gt;
        &lt;/dependency&gt;
12345</code></pre>
<h3 id="配置地址"><a href="#配置地址" class="headerlink" title=" 配置地址"></a> 配置地址</h3><p>  3、其次，修改各个服务的/src/main/resources/application.yml配置文件中配置 Nacos Server 地址</p>
<pre><code> spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
1</code></pre>
<h3 id="开启服务"><a href="#开启服务" class="headerlink" title=" 开启服务"></a> 开启服务</h3><p>  4、然后在SpringBoot启动类添加@EnableDiscoveryClient 注解开启服务注册与发现功能</p>
<h3 id="启动Nacos"><a href="#启动Nacos" class="headerlink" title=" 启动Nacos"></a> 启动Nacos</h3><p>  5、最后启动 Nacos Server，首先需要获取 Nacos Server，支持直接下载和源码构建两种方式。<br>  直接下载：<a target="_blank" rel="noopener" href="https://github.com/alibaba/nacos/releases">Nacos Server 下载页</a><br>  源码构建：进入 Nacos Github 项目页面，将代码 git clone 到本地自行编译打包。<br>  下载完后，运行启动 Server，进入解压后文件夹或编译打包好的文件夹，找到如下相对文件夹 nacos/bin，并对照操作系统实际情况之下如下命令。</p>
<pre><code>Linux/Unix/Mac 操作系统，执行命令 sh startup.sh -m standalone
Windows 操作系统，执行命令 cmd startup.cmd
12</code></pre>
<p>  6、Nacos Server 启动后，则可以启动项目，然后进入Nacos监控页面，则可以查看服务节点已经成功注册到 Nacos Server</p>
<blockquote>
<p><a target="_blank" rel="noopener" href="http://127.0.0.1:8848/nacos">http://127.0.0.1:8848/nacos</a><br>用户名和密码默认都为nacos</p>
</blockquote>
<p><a target="_blank" rel="noopener" href="https://nacos.io/zh-cn/docs/what-is-nacos.html">Nacos文档</a></p>
<h2 id="使用SpringCloud-OpenFeign远程调用服务"><a href="#使用SpringCloud-OpenFeign远程调用服务" class="headerlink" title="使用SpringCloud-OpenFeign远程调用服务"></a>使用SpringCloud-OpenFeign远程调用服务</h2><h3 id="引入依赖-1"><a href="#引入依赖-1" class="headerlink" title=" 引入依赖"></a> 引入依赖</h3><p>1.创建项目时引入依赖（谁需要调用服务则需要引入依赖）</p>
<pre class=" language-Java"><code class="language-Java">        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
1234</code></pre>
<h3 id="编写接口"><a href="#编写接口" class="headerlink" title=" 编写接口"></a> 编写接口</h3><p>2.编写一个接口，告诉SpringCloud这个接口需要调用远程服务</p>
<pre class=" language-Java"><code class="language-Java">@FeignClient("指定需要调用服务名")
public interface TestFeignService &#123;
    @RequestMapping("需要调用远程服务的controller方法全路径")
    //方法名和返回值，参数需要和远程调用方法一致
    public R testFeignMethod();

&#125;
1234567</code></pre>
<h3 id="开启调用"><a href="#开启调用" class="headerlink" title=" 开启调用"></a> 开启调用</h3><p>3.在项目启动类添加注解</p>
<pre class=" language-Java"><code class="language-Java">@EnableFeignClients("这里写上面创建接口的全包名")
1</code></pre>
<h3 id="使用服务"><a href="#使用服务" class="headerlink" title=" 使用服务"></a> 使用服务</h3><p>4.调用远程服务</p>
<pre class=" language-Java"><code class="language-Java">@RestController
@RequestMapping("member/member")
public class MemberController &#123;
    @Autowired
    private TestFeignService testFeignService;

    @RequestMapping("/test")
    public R test() &#123;
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("张三");

        R memberCoupons = testFeignService.testFeignMethod();
        return R.ok().put("member", memberEntity).put("coupons", memberCoupons.get("coupons"));
            &#125;
    &#125;
123456789101112131415</code></pre>
<h3 id="测试调用"><a href="#测试调用" class="headerlink" title=" 测试调用"></a> 测试调用</h3><p>5.接下来就可以启动项目测试输入<a target="_blank" rel="noopener" href="http://localhost:8000/member/member/test">http://localhost:8000/member/member/test</a> 成功页面<br><img src="https://img-blog.csdnimg.cn/2020040900342968.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<h3 id="调用过程"><a href="#调用过程" class="headerlink" title=" 调用过程"></a> 调用过程</h3><p>   调用过程：会先根据@EnableFeignClients注解指定的接口的全包名找到接口，然后通过@FeignClient注解指定的需要调用服务名找到服务（调用者和被调用者都需要注册到Nacos中），在根据方法名和指定的方法全路径找到远程服务方法进行调用。</p>
<h2 id="使用-Nacos-Config-Starter-完成微服务应用的服务注册与发现"><a href="#使用-Nacos-Config-Starter-完成微服务应用的服务注册与发现" class="headerlink" title="使用 Nacos Config Starter 完成微服务应用的服务注册与发现"></a>使用 Nacos Config Starter 完成微服务应用的服务注册与发现</h2><h3 id="引入依赖-2"><a href="#引入依赖-2" class="headerlink" title=" 引入依赖"></a> 引入依赖</h3><p>1、在公共项目pom.xml文件中添加依赖</p>
<pre><code> &lt;!--        配置中心来做配置管理--&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-config&lt;/artifactId&gt;
        &lt;/dependency&gt;
12345</code></pre>
<h3 id="配置地址-1"><a href="#配置地址-1" class="headerlink" title=" 配置地址"></a> 配置地址</h3><p>2、在应用的 /src/main/resources/bootstrap.properties 配置文件中配置 Nacos Config 元数据</p>
<pre><code> spring.application.name=服务名
 spring.cloud.nacos.config.server-addr=127.0.0.1:8848
12</code></pre>
<p>SpringBoot中有以下两种配置文件bootstrap (.yml 或者 .properties)，application (.yml 或者 .properties)</p>
<blockquote>
<p>1、加载顺序上的区别： 在 Spring Boot 中有两种上下文，一种是 bootstrap, 另外一种是application, bootstrap 是应用程序的父上下文，也就是说 bootstrap 加载优先于applicaton。bootstrap主要用于从额外的资源来加载配置信息，还可以在本地外部配置文件中解密属性。这两个上下文共用一个环境，它是任何Spring应用程序的外部属性的来源。bootstrap 里面的属性会优先加载，它们默认也不能被本地相同配置覆盖。<br>2、应用场景：bootstrap.yml 和application.yml 都可以用来配置参数。 bootstrap配置文件可以理解成系统级别的一些参数配置，这些参数一般是不会变动的。 application 配置文件可以用来定义应用级别的，主要用于 Spring Boot 项目的自动化配置。bootstrap 配置文件有以下几个应用场景：使用 Spring Cloud Config 配置中心时，这时需要在 bootstrap配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息，一些固定的不能被覆盖的属性，一些加密/解密的场景。</p>
</blockquote>
<h3 id="发布配置"><a href="#发布配置" class="headerlink" title=" 发布配置"></a> 发布配置</h3><p>3、完成上述两步后,使用的 Nacos自带控制台发布配置<br><img src="https://img-blog.csdnimg.cn/20200409221258627.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20200409221305848.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="'"></p>
<blockquote>
<p>dataId和group在项目启动日志控制台中可以找到：<br>例：Loading nacos data, dataId:‘gulimall-coupon.properties’, group: ‘DEFAULT_GROUP</p>
</blockquote>
<blockquote>
<p>修改group需要在配置文件中添加spring.cloud.nacos.config.group=MY_GROUP<br>注：该配置必须放在 bootstrap.properties 文件中</p>
</blockquote>
<p>还可以在命令行中发布配置：</p>
<pre><code>curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos-config-example.properties&amp;group=DEFAULT_GROUP&amp;content=user.id=1%0Auser.name=james%0Auser.age=17"
1</code></pre>
<h3 id="注入配置"><a href="#注入配置" class="headerlink" title=" 注入配置"></a> 注入配置</h3><p>3、发布成功配置后启动应用会从 <code>Nacos Config</code> 中获取相应的配置，并添加在 <code>Spring Environment</code> 的 <code>PropertySources</code> 中。使用 <code>@Value</code> 注解来将对应的配置注入到 <code>SampleController</code> 的 <code>userName</code> 和 <code>age</code> 字段，并添加<code>@RefreshScope</code> 打开动态刷新功能</p>
<pre class=" language-Java"><code class="language-Java"> @RefreshScope
 class SampleController &#123;

     @Value("$&#123;user.name&#125;")
     String userName;

     @Value("$&#123;user.age&#125;")
     int age;

    @RequestMapping("/testNacosConfig")
    public R testNacosConfig()&#123;
        return R.ok().put("userName",userName).put("age",age);
    &#125;
 &#125;
1234567891011121314</code></pre>
<h3 id="读取配置"><a href="#读取配置" class="headerlink" title=" 读取配置"></a> 读取配置</h3><p>4、启动项目打开自定义路径可以看到读取到之前配置的属性值</p>
<pre><code>&amp;#123;
"msg": "success",
"code": 0,
"userName": "DAIHAO",
"age": 18
&amp;#125;
123456</code></pre>
<p>修改配置则只需要在Nacos Cofig中修改配置重新发布即可，@RefreshScope注解会动态刷新读取配置中心的配置</p>
<h2 id="Nacos概念"><a href="#Nacos概念" class="headerlink" title="Nacos概念"></a>Nacos概念</h2><p><strong>1、\</strong>命名空间****：配置隔离；</p>
<ul>
<li>默认：public(保留空间)；默认新增的所有配置都在public空间。</li>
<li>1）、开发，测试，生产：利用命名空间来做环境隔离。<br>注意：在bootstrap.properties；配置上，需要使用哪个命名空间下的配置<br><code>spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871</code></li>
<li>2）、每一个微服务之间互相隔离配置，每一个微服务都创建自己的命名空间，只加载自己命名空间下的所有配置<br><img src="https://img-blog.csdnimg.cn/20200409224943995.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></li>
</ul>
<p><strong>2、\</strong>配置集****：即所有的配置的集合。一组相关或者不相关的配置项的集合称为配置集。在系统中，一个配置文件通常就是一个配置集，包含了系统各个方面的配置。例如，一个配置集可能包含了数据源、线程池、日志级别等配置项。</p>
<p><strong>3、\</strong>配置集ID****：Nacos 中的某个配置集的 ID( Data ID)。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集，每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包（如 com.taobao.tc.refund.log.level）的命名规则保证全局唯一性。此命名规则非强制。</p>
<p><strong>4、配置分组</strong>：默认所有的配置集都属于：DEFAULT_GROUP；<br>    项目中的使用：每个微服务创建自己的命名空间，使用配置分组区分环境，dev，test，prod</p>
<p><strong>5、同时加载多个配置集</strong></p>
<ul>
<li>1)、微服务任何配置信息，任何配置文件都可以放在配置中心中</li>
<li>2)、只需要在bootstrap.properties说明加载配置中心中哪些配置文件即可</li>
<li>3)、在这里插入图片描述以前SpringBoot任何方法从配置文件中获取值，都能使用。配置中心有的优先使用配置中心中的</li>
</ul>
<p><strong>将配置集拆分开</strong><br>可分别配置在开发环境下不同服务的配置<br><strong>数据源配置</strong><img src="https://img-blog.csdnimg.cn/20200409225653734.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="将配置集拆分开"><br>mybatis配置<img src="https://img-blog.csdnimg.cn/20200409225917440.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="将配置集拆分开"><img src="https://img-blog.csdnimg.cn/20200409225923780.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>在bootstrap.properties配置文件中配置要读取的配置<br><img src="https://img-blog.csdnimg.cn/20200409225931911.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在bootstrap.properties配置文件中配置要读取的配置"><br>还有一些概念有可以官方文档查看<a target="_blank" rel="noopener" href="https://nacos.io/zh-cn/docs/what-is-nacos.html">Nacos文档</a></p>
<h2 id="Nacos和zookeeper"><a href="#Nacos和zookeeper" class="headerlink" title="Nacos和zookeeper"></a>Nacos和zookeeper</h2><table>
<thead>
<tr>
<th>特性</th>
<th>zookeeper</th>
<th>nacos</th>
</tr>
</thead>
<tbody><tr>
<td>一致性协议</td>
<td>CP</td>
<td>CP + AP</td>
</tr>
<tr>
<td>健康检查</td>
<td>Keep Alive</td>
<td>tcp/http/mysql/client beat</td>
</tr>
<tr>
<td>负载均衡</td>
<td>无</td>
<td>权重/selector/metadata</td>
</tr>
<tr>
<td>多数据中心</td>
<td>不支持</td>
<td>支持</td>
</tr>
<tr>
<td>跨注册中心同步</td>
<td>不支持</td>
<td>支持</td>
</tr>
<tr>
<td>雪崩保护</td>
<td>无</td>
<td>有</td>
</tr>
<tr>
<td>访问协议</td>
<td>tcp</td>
<td>http/dns</td>
</tr>
<tr>
<td>k8s集成</td>
<td>不支持</td>
<td>支持</td>
</tr>
<tr>
<td>dubbo集成</td>
<td>支持</td>
<td>支持</td>
</tr>
</tbody></table>
<h2 id="Nacos原理"><a href="#Nacos原理" class="headerlink" title="Nacos原理"></a>Nacos原理</h2><h3 id="心跳机制"><a href="#心跳机制" class="headerlink" title="心跳机制"></a>心跳机制</h3><p>每5秒对心跳请求ip地址更新心跳时间，有个定时任务每5s会检查是不是太久没心跳，如果没心跳就下线掉这个实例</p>
<p>怎么发起的心跳请求：nacos定时向所有的nacos服务中心服务器发送心跳</p>
<h3 id="Nacos服务注册发现步骤"><a href="#Nacos服务注册发现步骤" class="headerlink" title="Nacos服务注册发现步骤"></a>Nacos服务注册发现步骤</h3><p>1、服务提供者将注册信息写入到Nacos注册中心的服务注册表中</p>
<p>2、服务注册中心将服务提供者的实例交给Service Holder（服务持有容器）处理，服务实例将会挂载在Service Holder的空间下</p>
<p>3、服务注册成功后，提供者将与服务中心维持心跳，未能及时发送心跳的服务将会被剔除</p>
<p>4、服务发现支持两种场景</p>
<p>消费者可以直接向注册中心发送获取某个服务实例的请求，这种情况下注册中心将返回所有可用的服务实例给消费者，但是一般不推荐这种情况。</p>
<p>服务的消费者向注册中心订阅某个服务，并提交一个监听器，当注册中心中服务发生变更时，监听器会收到通知，这时消费者更新本地的服务实例列表，以保证所有的服务均是可用的。<br><img src="https://img-blog.csdnimg.cn/20200516093836789.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RfQV9JX0hfQV9P,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<h3 id="负载均衡"><a href="#负载均衡" class="headerlink" title="负载均衡"></a>负载均衡</h3><p>负载均衡有很多中实现方式，包括轮询法，随机方法法，对请求ip做hash后取模等等，从负载的维度考虑又分为：服务端负载均衡和客户端负载均衡。</p>
<p>Nacos 的客户端在获取到服务的完整实例列表后，会在客户端进行负载均衡算法来获取一个可用的实例，模式使用的是随机获取的方式。Spring Cloud Alibaba、Nacos注册与发现</p>
<script>
        document.querySelectorAll('.github-emoji')
          .forEach(el => {
            if (!el.dataset.src) { return; }
            const img = document.createElement('img');
            img.style = 'display:none !important;';
            img.src = el.dataset.src;
            img.addEventListener('error', () => {
              img.remove();
              el.style.color = 'inherit';
              el.style.backgroundImage = 'none';
              el.style.background = 'none';
            });
            img.addEventListener('load', () => {
              img.remove();
            });
            document.body.appendChild(img);
          });
      </script>
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">guoxiaolong</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="http://carlosgxl.gitee.io/blog/2020/08/10/spring-cloud-alibaba-nacos-zhu-ce-yu-fa-xian/">http://carlosgxl.gitee.io/blog/2020/08/10/spring-cloud-alibaba-nacos-zhu-ce-yu-fa-xian/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">guoxiaolong</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            <span class="chip bg-color">无标签</span>
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/2020/08/10/spring-cloud-feign-she-ji-yuan-li/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/0.jpg" class="responsive-img" alt="">
                        
                        <span class="card-title"></span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            Spring Cloud Feign设计原理Spring Cloud Feign设计原理：什么是Feign？Feign 的英文表意为“假装，伪装，变形”， 是一个http请求调用的轻量级框架，可以以Java接口注解的方式调用Http请求，而
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2020-08-10
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-user fa-fw"></i>
                            guoxiaolong
                            
                        </span>
                    </div>
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/2020/08/10/14-springcloud-zu-jian/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/0.jpg" class="responsive-img" alt="">
                        
                        <span class="card-title"></span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            一、SpringCloud Alibaba1、SpringCloud Alibaba 简介1）、简介2）、为什么使用？3）、版本选择4）、项目中的依赖2、SpringCloud Alibaba-Nacos(作为注册中心)1）、下载 naco
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2020-08-10
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-user fa-fw"></i>
                            guoxiaolong
                            
                        </span>
                    </div>
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


<!-- 代码块折行 -->

<style type="text/css">
code[class*="language-"], pre[class*="language-"] { white-space: pre !important; }
</style>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="503838841"
                   fixed='true'
                   autoplay='true'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            <span id="year">2019</span>
            <a href="/about" target="_blank">guoxiaolong</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/Guo119741" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:1197814431@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=1197814431" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 1197814431" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script src="/js/search.js"></script>
<script type="text/javascript">
$(function () {
    searchFunc("/search.xml", 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
